home *** CD-ROM | disk | FTP | other *** search
- Path: news.delphi.com!usenet
- From: Derek Harmon <stonelight@delphi.com>
- Newsgroups: comp.lang.c
- Subject: Re: need convertion from char far* to char near *?
- Date: Tue, 30 Jan 96 12:52:37 -0500
- Organization: Delphi (info@delphi.com email, 800-695-4005 voice)
- Message-ID: <JlCqgr9.stonelight@delphi.com>
- References: <4ej91m$12ei@flood.weeg.uiowa.edu>
- NNTP-Posting-Host: bos1f.delphi.com
- X-To: Krzysztof Cwalina <kcwalina@blue.weeg.uiowa.edu>
-
- ** Quoting a message from <kcwalina@blue.weeg.uiowa.edu> dated <29-Jan-1996>:
-
- > I'm working on PC and I have a problem:
-
- > I wan't to use atoi but it only works with near strings. Unfortunately, I
- > have a far char pointer and I don't know how to convert it into a near
- > one.
-
- A near pointer is good only within a 64K segment, it is 2-bytes long,
- hence, it can be in the range of 0 to 65,535. Your PC knows where in
- memory this is, because it adds this offset to the 16-bit DS (Data Segment)
- register, allowing you to address any one 64K segment of memory in a 32-bit
- address space. Sneaky, those folks at Intel, huh?
-
- In the PC's Compact, Large and Huge memory models, you can have up to 1
- MB of static data. To accomplish this, all pointers are implicitly made far.
- What this means is the DS, which was previously the implied upper 16-bits of
- any near pointer's effective address, is no longer consulted. Instead, a
- far pointer is 4-bytes long, with its own segment (first 16-bits) and offset
- (last 16-bits). This means it can point anywhere it darn well pleases.
-
- I explain this to emphasize my two points in responding to your question.
-
- 1) It is "impossible" to behead a 4-byte far pointer into a 2-byte near
- pointer. You would irrevocably lose information. The reverse, to extend
- a 2-byte near pointer into a 4-byte far pointer, is trivial and can be type-
- cast normally. Having said this, an exception is when the segment of the
- far pointer is equal to the Data Segment, and it is hence equivalent to a
- near pointer (speaking strictly of Turbo C++, the compiler appears to do
- this with statically declared far pointers, at least the first 64KB worth).
-
- 2) The people who invented the convoluted scheme of these Memory Models
- and write compiler libraries, already know this. So, I suggest this pearl
- of programming wisdom:
-
- When you run into difficult memory constraints... compile using the next
- bigger memory model! :)
-
- Most PC compilers I can think of, certainly from Microsoft or Borland,
- will have libraries in each memory model, employing whatever pointer is the
- norm. I would suggest going into your compiler's Compiler or Linker Options
- and set to the Large Memory Model.
-
- In your example,
-
- (Using Small memory model: Near code and Near data, CS != DS)
-
- (i.) char *number; /* by default, this is a near pointer */
- int value;
- :
- value = atoi(number); /* this will work fine */
-
- (ii.) char far *number; /* overriding normal near pointer, making it far */
- int value;
- :
- value = atoi(number); /* CRASH! atoi() expects near */
- /* Note: Worked in TC++, again I suspect it sets far segment to DS */
- /* when it can. Let's just say this is a bad idea to try. :) */
-
- (iii.) char far *number; /* overriding normal near pointer, making it far */
- int value;
- :
- value = atoi((near)number); /* CRASH! atoi() only gets offset */
- /* Note: Again, this might work when Seg(number) == DS. Bad idea. */
-
- (Using Large memory model: Far code and Far data)
-
- (iv.) char *number; /* by default, this is a far pointer */
- int value;
- :
- value = atoi(number); /* fine, as atoi() expects a far pointer */
- /* atoi() also uses a far jump and return, so your code doesn't */
- /* have to necessarily fit into one 64KB code segment */
-
- (v.) char near *number; /* overriding default far pointer */
- int value;
- :
- value = atoi(number); /* atoi() expects a far pointer, but TC++ */
- /* will implicitly extend number to make the segment DS. */
-
- (vi.) char near *number; /* overriding default far pointer */
- int value;
- :
- value = atoi((far)number); /* this is the proper typecast & works */
-
- Try reading up on the linking options for your specific compiler so that
- you can link the larger memory model versions of the standard libraries
- into your program. Borland's Turbo C++ includes C0x.OBJ (program start-up
- module), MATHx.LIB, and Cx.LIB (standard library) for each memory model x
- (where x is the first letter of the model, ie, 's' for small, 'h' for huge).
-
- - Stone
-
- --
- ... recursive, adj. see recursive.
-